package com.plian.system.service.bt.baseinfo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.plian.Tools.Tools;
import com.plian.Tools.Tree;
import com.plian.Tools.TreeUtli;
import com.plian.Tools.UuidUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.cache.DictCache;
import com.plian.system.constant.baseinfo.ValueSetConstant;
import com.plian.system.dao.bt.baseinfo.BaseInfoDao;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class BaseInfoService {
    @Autowired
    BaseInfoDao baseInfoDao;
    /**
     * logger属性.
     */
    private static final Logger LOGGER  = LoggerFactory.getLogger(BaseInfoDao.class);
    /**
     * 主页列表 树表
     *
     * @return
     */
    public ListResult list(PageData pd) {
        ListResult listResult;
        try {
            List<Tree> list = new ArrayList<>();
            if (null != pd.getString("parentId") && !"".equals(pd.getString("parentId"))) {                     //如果有父节点，如职务等,分配给下属单位

            } else {                      //无父节点
                list = baseInfoDao.findTree(null);
                list = new TreeUtli().getTree(list, "parentId", "Code");
            }
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 保存
     *
     * @param pd
     * @return
     */
    public ObjResult save(PageData pd) {
        ObjResult objResult;
        try {
            if (Tools.isEmpty(pd.getString("parentId"))) {
                pd.put("parentId", "0");
            }
            if (null == baseInfoDao.findbycode(pd.getString("code"))) {
                //查询上级节点
                if (!"0".equals(pd.getString("parentId"))) {
                    PageData pageData = baseInfoDao.findbycode(pd.getString("parentId"));
                    if (pageData.getString("isParent") == null) {
                        pageData.put("isParent", "0");
                    }
                    if ("0".equals(pageData.getString("isParent"))) {
                        pageData.put("isParent", "1");
                    }
                    baseInfoDao.edit(pageData);
                    DictCache.update(pageData.getString("code"));
                }
                pd.put("id", UuidUtil.get32UUID());
                pd.put("isParent", "0");
                baseInfoDao.save(pd);
                DictCache.update(pd.getString("code"));
                objResult = new ObjResult(CommonCode.SUCCESS);
                DictCache.update(pd.getString("code"));
            } else {
                objResult = new ObjResult(CommonCode.EXIST);
            }

        } catch (Exception e) {
            objResult = new ObjResult(CommonCode.FAIL);
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
        return objResult;
    }

    /**
     * 修改
     *
     * @param pd
     * @return
     */
    public ObjResult edit(PageData pd) {
        ObjResult objResult;
        if (pd.getString("id").equals(pd.getString("parentId"))) {
            objResult = new ObjResult(CommonCode.FAIL);
            objResult.setMessage("父节点不能为自己本身!");
        } else {
            try {
                if (!"0".equals(pd.getString("parentId"))) {
                    PageData pageData = baseInfoDao.findbycode(pd.getString("parentId"));
                    if (pageData.getString("isParent") == null) {
                        pageData.put("isParent", "0");
                    }
                    if ("0".equals(pageData.getString("isParent"))) {
                        pageData.put("isParent", "1");
                    }
                    baseInfoDao.edit(pageData);
                    DictCache.update(pageData.getString("code"));
                }
                baseInfoDao.edit(pd);
                DictCache.update(pd.getString("code"));
                objResult = new ObjResult(CommonCode.SUCCESS);
            } catch (Exception e) {
                objResult = new ObjResult(CommonCode.FAIL);
                LOGGER.error(ExceptionUtils.getStackTrace(e));
            }
        }
        return objResult;
    }

    /**
     * 删除
     *
     * @return
     */
    public ObjResult del_ids(PageData pageData) {
        ObjResult objResult;
        try {
            if (!Tools.isEmpty(pageData.getString("id"))) {
                PageData dict = baseInfoDao.findById(pageData);
                baseInfoDao.delete(pageData);
                DictCache.evict(dict.getString("CODE"));
                objResult = new ObjResult(CommonCode.SUCCESS);
            } else {
                objResult = new ObjResult(CommonCode.FAIL);
            }
        } catch (Exception e) {
            objResult = new ObjResult(CommonCode.FAIL);
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
        return objResult;
    }

    /**
     * 根据id查询
     *
     * @param p
     * @throws Exception
     */
    public ObjResult findbyid(PageData p) {
        ObjResult objResult;
        try {
            PageData p_user = baseInfoDao.findById(p);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p_user);
        } catch (Exception e) {
            objResult = new ObjResult(CommonCode.ERROR);
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return objResult;
        }
        return objResult;
    }

    /**
     * 通过父节点CODE 查询数据
     *
     * @param p
     * @return
     */
    public ObjResult findbyParentid(PageData p) {
        ObjResult objResult;
        try {
            String string = p.getString("parentId");
            List<Tree> TreeNode = baseInfoDao.findTree(p);
            for (Tree treeNode : TreeNode) {
                for (Tree tree : TreeNode) {
                    if (tree.getCode().equals(treeNode.getParentId())) {
                        if (tree.getChildren() == null) {
                            tree.setChildren(new ArrayList<Tree>());
                        }
                        tree.getChildren().add(treeNode);
                    }
                }
            }
            PageData pageData = new PageData();
            TreeNode.removeIf(treeNode ->
                    treeNode.getParentId() != null && !string.contains(treeNode.getParentId()));
            for (String arr :string.replace("[","").replace("]","").split(",")) {
                List<Tree> treeNode =  new ArrayList<Tree>();
                for ( Tree tree:
                     TreeNode) {
                    if(tree.getParentId().equals(arr.trim())){
                        treeNode.add(tree);
                    }
                }
                pageData.put(arr.trim(),JSONArray.parseArray(JSON.toJSONString(treeNode)));
            }
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(pageData);
        } catch (Exception e) {
            objResult = new ObjResult(CommonCode.SUCCESS);
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return objResult;
        }
        return objResult;
    }

    public List<Tree> findThisChi(String string) throws Exception {
        PageData pageData1 = new PageData();
        List<String> codes = new ArrayList<>();
        codes.add(string.trim());
        pageData1.put("parentId", codes);
        List<Tree> TreeNode = baseInfoDao.findTree(pageData1);
        for (Tree treeNode : TreeNode) {
            if (!"0".equals(treeNode.getIsParent())) {
                treeNode.setChildren(findThisChi(treeNode.getCode()));
            }
        }
        return TreeNode;
    }

    public Map<String, String> getChildMap(String code) {
        Map<String, String> map = new HashMap<>();
        try {
            if (code.equals(ValueSetConstant.ROOT)){
                List<PageData> allChildTree = baseInfoDao.listAll(null);
                if (CollectionUtils.isEmpty(allChildTree)){
                   return map;
                }
                for (PageData pd : allChildTree){
                    map.put((String)pd.get("code"), (String)pd.get("name"));
                }
            }else {
                List<String> codes = new ArrayList<>();
                codes.add(code.trim());
                PageData pageData1 = new PageData();
                pageData1.put("parentId", codes);
                List<Tree> allChildTree = baseInfoDao.findTree(pageData1);
                return allChildTree.stream().collect(Collectors.toMap(Tree::getCode, Tree::getName,(a, b) -> b));
            }
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }

        return map;

    }

    public Map<String, String> getChildNameMap(String code) {
        List<Tree> allChildTree = new ArrayList<>();
        PageData pageData1 = new PageData();
        List<String> codes = new ArrayList<>();
        codes.add(code.trim());
        pageData1.put("parentId", codes);
        try {
            allChildTree = baseInfoDao.findTree(pageData1);

        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
        return allChildTree.stream().collect(Collectors.toMap(Tree::getName, Tree::getCode));
    }
}